package com.dcivision.dms.core;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.dms.bean.DmsRoot;
import com.dcivision.dms.dao.DmsDocumentDAObject;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.MessageResourcesFactory;
import com.dcivision.framework.PermissionManager;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.Utility;
import com.dcivision.user.bean.UserGroup;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.user.dao.UserGroupDAObject;
import com.dcivision.user.dao.UserRoleDAObject;


/**
 * <p>Class Name:       ParaScanManager.java    </p>
 * <p>Description:      The class mainly handle the ParaScan Jsp required function</p>
 * @author              Roy Wong
 * @company             DCIVision Limited
 * @creation date       15/02/2005
 * @version             $Revision: 1.4.2.1 $
 */

public class ParaScanManager {
  public static final String REVISION = "$Revision: 1.4.2.1 $";
  private SessionContainer sessionContainer;
  private Connection conn;
  protected Log log = LogFactory.getLog(this.getClass().getName());
  
  /**
   *  Constructor - Creates a new instance of ParaScanManager
   */
  public ParaScanManager(SessionContainer sessionContainer, Connection conn) {
    this.sessionContainer = sessionContainer;
    this.conn = conn;
  }
  
  /**
   *  Release - release all variable in instance of ParaScanManager
   */
  public synchronized void release() {
    this.sessionContainer = null;
    this.conn = null;
  }
  
  /**
    *  Gets the session container of the specific user
    *
    *  @param      userRecord               The userRecord bean of specific user
    *  @param      userIP                   The IP address of the user request
    *  @return     userSession              The sessionContainer of the specific user
    */
  
  public SessionContainer getUserSession(UserRecord userRecord, String userIP){
    SessionContainer userSession = new SessionContainer();
    userSession.setUserIPAddress(userIP);
    try{
    
       // Get User Groups Information.
       UserGroupDAObject userGroupDAO = new UserGroupDAObject(userSession, conn);
       List userGroups = userGroupDAO.getListByUserRecordIDGroupType(userRecord.getID(), com.dcivision.user.bean.UserGroup.GROUP_TYPE_PUBLIC);
       userSession.getPermissionManager().setUserGroups(userGroups);

       // Get User Roles and Group Role Information (Union them with no duplicate roles).
       UserRoleDAObject userRoleDAO = new UserRoleDAObject(userSession, conn);
       List userRoles = userRoleDAO.getListByUserRecordID(userRecord.getID());

       for (int i = 0; i < userGroups.size(); i++) {
         UserGroup tmpUserGroup = (UserGroup) userGroups.get(i);
         List userRolesByGroup = userRoleDAO.getListByUserGroupID(tmpUserGroup.getID());
         for (int j = 0; j < userRolesByGroup.size(); j++) {
           if (!userRoles.contains(userRolesByGroup.get(j))) {
               userRoles.add(userRolesByGroup.get(j));
              
           }
         }
       }

      userSession.getPermissionManager().setUserRoles(userRoles);
      userSession.setUserRecord(userRecord);
    
    }catch(ApplicationException appEx){
      log.error(appEx, appEx);
    }catch(Exception ex){
      log.error(ex, ex);
    }
    
    return userSession;
  }
  
  /**
   * Checks the user has the rights to access the object with specified permission code
     *
   * @param objectType       the object type
   * @param objectID         the object ID 
   * @param rootID           the root ID
   * @param permissionCode   the permission for checking
   * @param sessionContainer SessionContainer
   * @return
   * @throws ApplicationException
     */
  
  public boolean checkHasPermissionOnObject(String objectType, Integer objectID, Integer rootID, String permissionCode,SessionContainer sessionContainer) throws ApplicationException {
    boolean havePermission = false;
    
   
    PermissionManager permissionManager = sessionContainer.getPermissionManager();
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    RootRetrievalManager rootManager = new RootRetrievalManager(sessionContainer, conn);
    DmsRoot root = rootManager.getRootObject(rootID);
   

      boolean hasRight = false;
      String permission = null;
      DmsDocument dmsObj = null;
      if (objectID.intValue() != 0) {
        dmsObj = docRetrievalManager.getDocument(objectID);
        try {
          permission = permissionManager.getPermission(objectType, objectID);
        } catch (ApplicationException appEx) {
          log.error(appEx, appEx);
          permission = "";
        }

        log.debug(" objectID: " + objectID + ", permission: " + permission);

        if (permission.indexOf(permissionCode) < 0) {
          String actionTryToCarryOut = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.permission_" + permissionCode);
          return false;
          //throw new ApplicationException(DmsErrorConstant.HAVE_NO_FUNCTION_PERMISSION, null, actionTryToCarryOut);
        }
      }
      if (objectID.intValue() == 0) {
        try {
          dmsObj = docRetrievalManager.getRootFolderByRootID(rootID);
          permission = permissionManager.getPermission(objectType, dmsObj.getID());
        } catch (ApplicationException appEx) {
          log.error(appEx, appEx);
          permission = "";
        }

        log.debug(" ID: " + dmsObj.getID() + ", permission: " + permission);
        if (permission.indexOf(permissionCode) < 0) {
          String actionTryToCarryOut = MessageResourcesFactory.getMessage(sessionContainer.getSessionLocale(), "dms.label.permission_" + permissionCode);
          return false;
          //throw new ApplicationException(DmsErrorConstant.HAVE_NO_FUNCTION_PERMISSION, null, actionTryToCarryOut);
        }
      }
    //}
    docRetrievalManager.release();
    rootManager.release();
    return true;
  }
  
  /**
   * Generates stringBuffer in XML format for the folder structure
   * <P>
   * The folder structure generates base on the parent id , root ID and level No, the level no specified
   * the folder level to generate.
   * This method mainly use for jsp/scan/ParaScanGetAllFolder.jsp
   * </P>
   * @param parentID  the document(folder) parent id
   * @param rootID    the document(folder) root ID
   * @param levelNo   the level No.
   * @param request   HttpServletRequest request
   * @return folder structure in xml format
   * @throws ApplicationException
   */
  public StringBuffer getFolderTreeByParentIDRootID(Integer parentID, Integer rootID,int levelNo,HttpServletRequest request) throws ApplicationException {
    Integer runNoObj = (Integer)request.getAttribute("ParaScanRunNo");
    int runNo = runNoObj!=null?runNoObj.intValue():0;
    runNo++;
    request.setAttribute("ParaScanRunNo",new Integer(runNo));
    StringBuffer Folder = (StringBuffer)request.getAttribute("ParaScanFolder");
    Folder= Folder !=null? Folder:new StringBuffer();
    
      
    DmsDocumentDAObject dmsDocumentDAO = new DmsDocumentDAObject(sessionContainer, conn);
    List documentList = dmsDocumentDAO.getListByParentID(parentID, rootID, DmsDocument.FOLDER_TYPE);
    List finalList = new ArrayList();
    List tmpList = null;
   
    finalList.addAll(documentList);
    if (!Utility.isEmpty(documentList)) {
      for (int i=0; i<documentList.size(); i++) {
        DmsDocument doc = (DmsDocument)documentList.get(i);           
        Folder.append("<Folder FolderId=\""+doc.getID()+"\" ParentId=\""+doc.getParentID()+"\" Name=\""+doc.getDocumentName()+"\">");
        if(levelNo!=0){
          if(runNo<=levelNo){ 
            Folder = getFolderTreeByParentIDRootID(doc.getID(), null,levelNo,request);
          }
        }else{
          Folder = getFolderTreeByParentIDRootID(doc.getID(), null,levelNo,request); 
        }
        Folder.append("</Folder>");      
      
      }
    }
    
    dmsDocumentDAO=null;
    request.setAttribute("ParaScanFolder",Folder);
    return Folder;
    
  
  }
  

}
